package club.janna.netty.encode;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import java.util.Arrays;
import java.util.List;

/**
 * 解码器-服务端
 */
public class DecodeServer {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup boosGroup = new NioEventLoopGroup(1);
        EventLoopGroup workGroup = new NioEventLoopGroup();

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(boosGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(50, 1, 2, 0, 1));
                        ch.pipeline().addLast(new UserDecoder());
                        ch.pipeline().addLast(new BizHandler());
                    }
                });
        ChannelFuture future = serverBootstrap.bind(8080).sync();
        System.out.println("启动成功，8080");
        future.channel().closeFuture().sync();
    }

    /**
     * 业务处理器，打印收到的数据
     */
    private static class BizHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            if(msg instanceof ByteBuf) {
                ByteBuf byteBuf = (ByteBuf) msg;
                byte[] bytes = new byte[byteBuf.readableBytes()];
                byteBuf.readBytes(bytes);
                System.out.println("收到数据 -> " + Arrays.toString(bytes));
                byteBuf.release();
            } else {
                System.out.println("收到数据 -> " + msg);
            }
        }
    }

    /**
     * 用户解码器
     *
     * +------+--------+------+------+----------+
     * | HEAD | Length | ID   | Age  | Name     |
     * | 0xCA | 0x0014 | 0x01 | 0x18 | guopanbo |
     * +------+--------+------+------+----------+
     */
    private static class UserDecoder extends ByteToMessageDecoder {
        @Override
        protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
            User user = decode(in);
            if(user != null)
                out.add(user);
        }

        /**
         * 读取user的属性，生成user对象
         * @param in
         * @return
         */
        private User decode(ByteBuf in) {
            short length = in.readShort();
            // name的长度 = 总长度 - id的长度 - age的长度
            int nameLength = length - 8 - 4;
            if(nameLength < 0) {
                throw new RuntimeException("length invalid");
            }
            if(in.readableBytes() < length - 2) { // 可读字节不够
                in.readerIndex(in.writerIndex());
                return null;
            }
            User user = new User();
            user.setId(in.readLong());
            user.setAge(in.readInt());

            // 读取name
            byte[] bytes = new byte[nameLength];
            in.readBytes(bytes);
            user.setName(new String(bytes));
            return user;
        }
    }
}
